#ifndef ZIPMAN_H_
#define ZIPMAN_H_

namespace LuaPlus
{
	class LuaState;
}
//#include "util/mmgr.h"
#include <vector>
#include <cassert>
#include <string.h>
#include <string>
// Singleton zip manager class.. univeral interface to loading files
namespace vfs
{
class Archive;

/***
 *	@brief:	Single data-block
 */
struct	LoadedBlock
{
	std::string			FileName;
	unsigned int		Size;
	unsigned char*		DataArray;
	unsigned int		Index;
	bool				ShouldDelete;
	LoadedBlock()	
	{	
		ShouldDelete = true;
		DataArray = NULL;
		Size	  = 0;
		Index	  = 0;
	}
	LoadedBlock(unsigned char* DataA, unsigned int		_Size)	
	{
		Size	  = _Size;
		DataArray = DataA;
		Index	  = 0;
	}
	~LoadedBlock()	
	{
		Erase();
	}
	void				Reset()
	{
		Erase();
		Index = 0;
	}
	void				ResetIndex()
	{
		Index = 0;
	}
	bool				IsEmpty()
	{
		return Index >=Size;
	}
	bool				ReadData(void* _Dest, unsigned long _Size)
	{
		if (Index + (int)_Size <= Size)
		{
			memcpy(_Dest, &DataArray[Index], _Size);
			Index+=_Size;
			return true;	
		}
		// failed the load. Set as empty
		Index=Size;
		return false;
	}
	void				Erase()
	{	
		if (DataArray && ShouldDelete)
			delete [] DataArray;
		DataArray = 0;
		Size = 0;
	}
};

	
class VFS
{
public:
	static VFS&						Instance();
	/**
	 * @brief:	load a file from disk
	 * @param _Name		Name of file to load
	 * @param _Block	Filled datablock
	 */
	bool							GetFile(const std::string& _Name, LoadedBlock& _Block);
	/**
	 * @brief:	Adds a new Zip File to the vfs
	 * @param	_Name		Name of zip file to add
	 * @param	Precache	Precache the entire archive at load? Usefull for dense archives	
	 * @returns				the valid archive, or NULL if it failed to load
	 */
	Archive*						AddArchive(const std::string& _Name, bool Precache = true);

	/// get the full path of the file from within the directories
	std::string						GetPath(const std::string& _File);

	bool							FileExists(const std::string& _Name);

	int								BuildFileList(std::vector<std::string>& List,
												  const std::string& Path,
												  const std::string& Ext = "");

	static std::string				GetExtension(const std::string& Name);
	static std::string				GetBaseName(const std::string& Name);
	static std::string				GetPathName(const std::string& Name);
	static std::string				GetFilename(const std::string& Name);
	static std::string				StripExtension(const std::string& Name);
private:

	/**
	 * @brief:	facilitate loading process
	 * @param _Name		Name of file to load
	 * @param _Block	Filled datablock
	 */
	bool							LoadLocal(const std::string& _Name, LoadedBlock& _Block);

	

	std::vector<Archive*>			m_Files;
									VFS();
									~VFS();
};

}

#endif // ZIPMAN_H_
